/*
 * p223.cpp
 *     sgu 223 n*n 的棋盘，放k个国王，使他们不能互相攻击，问有多少种放法。（国王攻击范围为他周围的8个点）
这题因为不满足每行只放一个的条件，所以不能像上一题那样解决。而且求解当前行，和上一行的状态有关，所以状态转移的时候需要上行的状态。
F[i][S][j]:前i行放j个国王，第i行状态为S的方案数。
F[i][S][j]=sum(F[i-1][S'][j-Count(S)]) S和S‘不冲突，Count（S）表示S中1的个数。
ans=Sum(F[i][S][K])
复杂度分析
状态数：N*2^N*K (N^2)=N^3*2^N,转移代价2^N

时间优化（减少状态数）：
每行的状态S不必要从0到2^N-1枚举，因为有些状态行内就冲突了！
补充：格子数为m的一行放棋子，相邻两个棋子中间的空格数不少于d的状态数：
Num=C(m,0)+C(m,1)+C(m-d,2)+C(m-2d,3)+......
可以dfs预处理出所有可行的状态，把可行的状态保存起来，本题的可行状态数大约减少为200个。总复杂度约为4*10^7
 */
#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
#include<string>
#include<vector>
#include<set>
#include<map>
#include<stack>
#include<queue>
#include<algorithm>
using namespace std;
long long dp[2][300][110], ans;
int s[300], c[300];//s保存一行的可行状态,c[i]表示状态s[i]中1的个数
int n, k, num = 0;//num存可行状态数

//预处理可行状态。dep:搜索深度，put:dep-1是否放国王，now:状态的值，cnt:1的个数
void dfs(int dep, bool put, int now, int cnt)//
{
	if (dep == n)
	{
		num++;
		s[num] = now;
		c[num] = cnt;
		return;
	}
	dfs(dep + 1, 0, now << 1, cnt);//第dep+1的位置不放国王
	if (!put)//放国王
		dfs(dep + 1, 1, (now << 1) + 1, cnt + 1);
}
bool check(int i, int j)
{
	return (s[i] & s[j]) || ((s[i] << 1) & s[j]) || ((s[i] >> 1) & s[j]);
}
int main()
{
	scanf("%d%d", &n, &k);
	dfs(0, 0, 0, 0);
	memset(dp, 0, sizeof(dp));
	dp[0][1][0] = 1;//边界
	for (int i = 1; i <= n; i++)
	{
		memset(dp[i & 1], 0, sizeof(dp[i & 1]));
		for (int t = 1; t <= num; t++)
			for (int j = c[t]; j <= k; j++)//第i行状态s[t],j最少为c[t]
				for (int tt = 1; tt <= num; tt++)//枚举i-1行的状态
				{
					if (check(t, tt))//检测两行是否冲突
						continue;
					dp[i & 1][t][j] += dp[(i - 1) & 1][tt][j - c[t]];

				}
	}
	ans = 0;
	for (int i = 1; i <= num; i++)
		ans += dp[n & 1][i][k];
	cout << ans << endl;
	return 0;
}
